package com.yuma.communication;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 多线程之间按顺序调用，实现AA->BB->CC。三个线程启动，要求如下：
 * AA打印5次，BB打印10次，CC打印15次 接着 AA打印5次，BB打印10次，CC打印15次
   。。。打印10轮
 */

class PrintNumber {
    private int flag = 1;
    private ReentrantLock lock = new ReentrantLock();
    private Condition aCondition = lock.newCondition();
    private Condition bCondition = lock.newCondition();
    private Condition cCondition = lock.newCondition();

    public void printA() {
        lock.lock();
        while(flag != 1){
            try {
                aCondition.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        for (int i = 0; i < 5; i++) {
            System.out.println("AA");
        }
        flag = 2;
        bCondition.signal();  // 唤醒第二个线程
        lock.unlock();
    }

    public void printB() {
        lock.lock();
        while(flag != 2){
            try {
                bCondition.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        for (int i = 0; i < 10; i++) {
            System.out.println("BB");
        }
        flag = 3;
        cCondition.signal();  // 唤醒第二个线程
        lock.unlock();
    }

    public void printC() {
        lock.lock();
        while(flag != 3){
            try {
                cCondition.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        for (int i = 0; i < 15; i++) {
            System.out.println("CC");
        }
        flag = 1;
        aCondition.signal();  // 唤醒第二个线程
        lock.unlock();
    }
}

public class ConditionPrintNumber {

    public static void main(String[] args) {
        PrintNumber printNumber = new PrintNumber();

        for(int i = 0 ;i < 10; i++){
            new Thread(()->{
                printNumber.printA();
            }).start();
            new Thread(()->{
                printNumber.printB();
            }).start();
            new Thread(()->{
                printNumber.printC();
            }).start();
        }
    }
}
